package com.bike.util;

import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

import javax.imageio.ImageIO;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.Binarizer;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.EncodeHintType;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.Result;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

/**
 * @Description: (二维码)
 * @author：yqgao
 * @date：2014-11-7 下午05:27:13
 */
public class ZXingCode {

	/**
	 * 给二维码图片添加Logo
	 *
	 * @param qrPic
	 * @param logoPic
	 */
	public void addLogo_QRCode(File qrPic, File logoPic, File diningPic, LogoConfig logoConfig, String filePath, String productName, String diningNum,PageData tempPd) {
		try {
			if (!qrPic.isFile() || !logoPic.isFile()) {
				System.out.print("file not find !");
			}
			
			Integer codeX=tempPd.getInteger("codeX");//二维码x坐标
			Integer codeY=tempPd.getInteger("codeY");//二维码y坐标
			Integer codeXX=tempPd.getInteger("codeXX");//桌名x坐标
			Integer codeYY=tempPd.getInteger("codeYY");//桌名y坐标
			Integer heightYY=tempPd.getInteger("heightYY");//二维码 距离 商家名称的距离
			Integer amount=tempPd.getInteger("amount");
			
			// 读取二维码图片，并构建绘图对象
			BufferedImage image = ImageIO.read(qrPic);
			// 读取Logo图片
			BufferedImage logo = ImageIO.read(logoPic);
			// 读取桌牌图片
			BufferedImage dining = ImageIO.read(diningPic);
			// 设置logo的大小,本人设置为二维码图片的20%,因为过大会盖掉二维码
			int widthLogo = logo.getWidth(null) > image.getWidth() * 2 / 10 ? (image.getWidth() * 2 / 10) : logo.getWidth(null);
			int heightLogo = logo.getHeight(null) > image.getHeight() * 2 / 10 ? (image.getHeight() * 2 / 10) : logo.getHeight(null);
			// logo放在中心位置
			int x = (image.getWidth() - widthLogo) / 2;
			int y = (image.getHeight() - heightLogo) / 2;
			// 开始绘制logo图片到二维码
			Graphics2D g = image.createGraphics();
			g.drawImage(logo, x, y, widthLogo, heightLogo, null);
			g.drawRoundRect(x, y, widthLogo, heightLogo, 15, 15);
			g.setStroke(new BasicStroke(logoConfig.getBorder()));
			g.setColor(logoConfig.getBorderColor());
			g.drawRect(x, y, widthLogo, heightLogo);
			g.dispose();
			// 文字这里最多支持两行。太长就会自动截取
			if (productName != null && !productName.equals("")) {
				// 新的图片，把带logo的二维码下面加上文字
				// BufferedImage outImage = image;
				// Graphics2D outg = outImage.createGraphics();
				// // 画二维码到新的面板
				// outg.drawImage(image, 0, 0, image.getWidth(),
				// image.getHeight(), null);
				// // 画文字到新的面板
				// outg.setColor(Color.BLACK);
				// outg.setFont(new Font("宋体", Font.BOLD, 40)); // 字体、字型、字号
				// int strWidth =
				// outg.getFontMetrics().stringWidth(productName);
				// outg.drawString(productName, (image.getWidth() - strWidth) /
				// 2, image.getHeight() - 3); // 画文字
				// outg.dispose();
				// outImage.flush();

				// 新建一个图片把店名放到下面
				BufferedImage outImage = new BufferedImage(image.getWidth() + 70, image.getHeight() + 150, BufferedImage.TYPE_4BYTE_ABGR);
				Graphics2D bioutg = outImage.createGraphics();
				bioutg.drawImage(image, 35, 0, image.getWidth(), image.getHeight(), null);
				// 画文字到新的面板
				// bioutg.setColor(Color.WHITE);
				bioutg.setFont(new Font("宋体", Font.BOLD, 70)); // 字体、字型、字号
				int strWidths = bioutg.getFontMetrics().stringWidth(productName);
				if(heightYY==null){
					heightYY=73;
				}
				if (strWidths > image.getWidth() + 70) {
					int count = (image.getWidth() +70) / 73;
					// 第一行
					bioutg.drawString(productName.substring(0, count), 0, image.getHeight() + heightYY);
					// 第二行
					bioutg.drawString(productName.substring(count, productName.length()), 0, image.getHeight() + heightYY*2); // 画文字
				} else {
					bioutg.drawString(productName, (image.getWidth() + 70 - strWidths) / 2, image.getHeight() + heightYY); // 画文字
				}
				bioutg.dispose();
				outImage.flush();

				// 增加桌牌背景图
				int bg_x = dining.getWidth() - 3244;
				int bg_y = dining.getHeight() - 678;
				// 第二个二维码坐标
				int bgX = dining.getWidth() - 652;
				int bgY = dining.getHeight() - 678;
				int two_code_height = outImage.getHeight();
				int two_code_width = outImage.getWidth();
				BufferedImage diningImage = dining;
				Graphics2D bgimg = diningImage.createGraphics();
				if(codeX!=null&&codeX>0){
					bg_x=codeX;
				}
				if(codeY!=null&&codeY>0){
					bg_y=codeY;
				}
				bgimg.drawImage(outImage, bg_x, bg_y, two_code_width, two_code_height, null);
				if(amount==null||amount>1){
					bgimg.drawImage(outImage, bgX, bgY, two_code_width, two_code_height, null);
				}
				// bgimg.drawRoundRect(bg_x, bg_y, two_code_width,
				// two_code_height, 15, 15);
				// bgimg.setStroke(new BasicStroke(logoConfig.getBorder()));
				// bgimg.setColor(logoConfig.getBorderColor());
				// bgimg.drawRect(bg_x, bg_y, two_code_width, two_code_height);
				// 写入桌号
				if(amount==null||amount>1){
					bgimg.setFont(new Font("微软雅黑", Font.BOLD, 120)); // 字体、字型、字号
				}else{
					bgimg.setColor(Color.black);
					bgimg.setFont(new Font("微软雅黑", Font.BOLD, 80)); // 字体、字型、字号
				}
				
				int width_dining = 150 + (diningNum.length() * 50);
				if (diningNum.equals("堂食")) {
					width_dining = 280;
				}
				
				int diningNumWidth = bgimg.getFontMetrics().stringWidth(diningNum);
				if(codeXX==null){
					codeXX=2302;
				}else{
					codeXX+=(320-diningNumWidth)/2;
				}
				if(codeYY==null){
					codeYY=622;
				}
				
				bgimg.drawString(diningNum, codeXX, codeYY); // 画文字
				
				bgimg.dispose();
				diningImage.flush();
				image = diningImage;
			}
			logo.flush();
			image.flush();
			dining.flush();
			ImageIO.write(dining, "png", new File(filePath));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 二维码的解析
	 *
	 * @param file
	 */
	public void parseQR_CODEImage(File file) {
		try {
			MultiFormatReader formatReader = new MultiFormatReader();
			if (!file.exists()) {
				return;
			}
			BufferedImage image = ImageIO.read(file);
			LuminanceSource source = new BufferedImageLuminanceSource(image);
			Binarizer binarizer = new HybridBinarizer(source);
			BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
			Map hints = new HashMap();
			hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
			Result result = formatReader.decode(binaryBitmap, hints);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 将二维码生成为文件
	 *
	 * @param bm
	 * @param imageFormat
	 * @param file
	 */
	public void decodeQR_CODE2ImageFile(BitMatrix bm, String imageFormat, File file) {
		try {
			if (null == file || file.getName().trim().isEmpty()) {
				throw new IllegalArgumentException("文件异常，或扩展名有问题！");
			}
			BufferedImage bi = fileToBufferedImage(bm);
			ImageIO.write(bi, "png", file);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 构建初始化二维码
	 *
	 * @param bm
	 * @return
	 */
	public BufferedImage fileToBufferedImage(BitMatrix bm) {
		BufferedImage image = null;
		try {
			int w = bm.getWidth(), h = bm.getHeight();
			image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
			for (int x = 0; x < w; x++) {
				for (int y = 0; y < h; y++) {
					image.setRGB(x, y, bm.get(x, y) ? 0xFF000000 : 0xFFCCDDEE);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return image;
	}

	/**
	 * 生成二维码bufferedImage图片
	 *
	 * @param content
	 *            编码内容
	 * @param barcodeFormat
	 *            编码类型
	 * @param width
	 *            图片宽度
	 * @param height
	 *            图片高度
	 * @param hints
	 *            设置参数
	 * @return
	 */
	public BufferedImage getQR_CODEBufferedImage(String content, BarcodeFormat barcodeFormat, int width, int height, Map<EncodeHintType, ?> hints) {
		MultiFormatWriter multiFormatWriter = null;
		BitMatrix bm = null;
		BufferedImage image = null;
		try {
			multiFormatWriter = new MultiFormatWriter();
			// 参数顺序分别为：编码内容，编码类型，生成图片宽度，生成图片高度，设置参数
			bm = multiFormatWriter.encode(content, barcodeFormat, width, height, hints);
			int w = bm.getWidth();
			int h = bm.getHeight();
			image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
			// 开始利用二维码数据创建Bitmap图片，分别设为白（0xFFFFFFFF）黑（0xFF000000）两色
			for (int x = 0; x < w; x++) {
				for (int y = 0; y < h; y++) {
					image.setRGB(x, y, bm.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
				}
			}
		} catch (WriterException e) {
			e.printStackTrace();
		}
		return image;
	}

	/**
	 * 设置二维码的格式参数
	 *
	 * @return
	 */
	public Map<EncodeHintType, Object> getDecodeHintType() {
		// 用于设置QR二维码参数
		Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
		// 设置QR二维码的纠错级别（H为最高级别）具体级别信息
		hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
		// 设置编码方式
		hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
		// 二维码白边
		hints.put(EncodeHintType.MARGIN, 1);
		return hints;
	}

/**
	 * 二维码图片的生成
	 * @param content			链接
	 * @param qrcode_width		二维码宽
	 * @param qrcode_height		二维码高
	 * @return
	 * @throws Exception
	 */
    public static BufferedImage createImage(String content, int qrcode_width, int qrcode_height) throws Exception {
        Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
        hints.put(EncodeHintType.MARGIN, 1);
        BitMatrix bitMatrix = new MultiFormatWriter().encode(content,
                BarcodeFormat.QR_CODE, qrcode_width, qrcode_height, hints);
        int width = bitMatrix.getWidth();
        int height = bitMatrix.getHeight();
        BufferedImage image = new BufferedImage(width, height,
                BufferedImage.TYPE_INT_RGB);
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000
                        : 0xFFFFFFFF);
            }
        }
        return image;
    }
	

    
    
	public static void main(String[] args) throws IOException {
		/*PageData tempPd=new PageData();
		tempPd.put("codeX", 270);//二维码的x坐标
		tempPd.put("codeY", 780);//二维码的y坐标
		tempPd.put("codeXX", 440);//桌名的x坐标
		tempPd.put("codeYY",1680);//桌名的y坐标
		tempPd.put("heightYY", 145);//商家名和二维码之间的距离
		tempPd.put("amount", 1);
		
		File outputFile = new File("D://dizhu/a.png");
		ZXingCode zp = new ZXingCode();
		BufferedImage bim = zp.getQR_CODEBufferedImage("http://fm.yunkejia.com.cn/asdfjij", BarcodeFormat.QR_CODE, 600, 600, zp.getDecodeHintType());
		ImageIO.write(bim, "png", outputFile);
		zp.addLogo_QRCode(outputFile, new File("D://dizhu/logo.png"), new File("D://work/chinamobile.png"), new LogoConfig(), "D://dizhu/b.jpg", "旮旯小炒旮旯小炒旮", "堂食e食",tempPd);
	*/
	
	}
}
